package handlers

import (
	"night-school-api/middlewares"
	"night-school-api/models"
	"night-school-api/utils"
	"night-school-api/database"
	// "os"
	// "fmt"
	"strconv"
	"time"

	"github.com/labstack/echo/v4"
)

// 定义 JSON 请求数据结构
type loginRequest struct {
	Code string `json:"code"`
}

type loginResponse struct {
	Token    string      `json:"token"`
	UserInfo models.User `json:"user_info"`
}


// 小程序登录
func MnpLogin(c echo.Context) error {
	var req loginRequest

	// 解析 JSON 请求
	if err := c.Bind(&req); err != nil {
		return utils.JSONError(c, "参数错误")
	}

	code := req.Code
	if code == "" {
		return utils.JSONError(c, "code不能为空")
	}
	c.Logger().Info("code:" + code)


	mnp, err := utils.InitMnp()
	if err != nil {
		c.Logger().Fatal("微信小程序初始化服务错误: " + err.Error())
		return utils.JSONError(c, "微信小程序初始化服务错误")
	}

	rs, err := mnp.Auth.Session(c.Request().Context(), code)
	if err != nil {
		c.Logger().Fatal("微信小程序登录失败: " + err.Error())
		return utils.JSONError(c, "微信小程序登录失败")
	}

	// session, err := utils.MnpLoginSessionInfo(code)
	// if err != nil {
	// 	c.Logger().Fatal("微信小程序登录失败: " + err.Error())
	// 	return utils.JSONError(c, "微信小程序登录失败")
	// }
	// c.Logger().Info(fmt.Sprintf("session: %#v", session))

	openid := rs.OpenID
	if openid == "" {
		return utils.JSONError(c, "微信小程序获取用户标识失败")
	}

	db := database.DB

	var user models.User
	db.Debug().Model(&models.User{}).Where("openid = ?", openid).First(&user)

	var now models.JSONTime
	now.Time = time.Now()

	c.Logger().Info(" Openid: " + openid + "user.ID:" + strconv.Itoa(user.ID))
	if user.ID == 0 {
		user = models.User{
			Name:        "",
			Openid:      openid,
			LastLoginAt: now,
		}
		db.Create(&user)
	} else {
		db.Model(&models.User{}).Where("id = ?", user.ID).Updates(map[string]interface{}{
			"last_login_at": now,
		})
	}

	// 生成token
	token, err := middlewares.GenerateToken(user.ID, "user")
	if err != nil {
		c.Logger().Info("系统错误，登录失败:" + err.Error())
		return utils.JSONError(c, "系统错误，登录失败")
	}

	data := loginResponse{
		Token:    token,
		UserInfo: user,
	}
	return utils.JSONSuccess(c, data, "")
}

// 模拟登录，测试用
func SimulateLogin(c echo.Context) error {
	u := c.QueryParam("uid")
	uid, err := strconv.Atoi(u)
	if err != nil {
		return utils.JSONError(c, "参数错误")
	}

	if uid <= 0 {
		return utils.JSONError(c, "参数错误")
	}

	token, err := middlewares.GenerateToken(uid, "user")

	db := database.DB
	var user models.User
	db.Model(&models.User{}).Where("id = ?", uid).First(&user)

	data := loginResponse{
		Token: token,
		UserInfo: user,
	}

	return utils.JSONSuccess(c, data, "")
}


// 小程序获取手机号
func MnpGetPhone(c echo.Context) error {
	uid := c.Get("uid").(int)

	var req map[string]interface{}

	if err := c.Bind(&req); err != nil {
		return utils.JSONError(c, "请求参数错误")
	}

	code, ok := req["code"].(string)
	if !ok {
		return utils.JSONError(c, "请求参数错误")
	}

	if code == "" {
		return utils.JSONError(c, "code不能为空")
	}

	mnp, err := utils.InitMnp()
	if err != nil {
		c.Logger().Fatal("微信小程序初始化服务错误: " + err.Error())
		return utils.JSONError(c, "微信小程序服务错误")
	}

	rs, err := mnp.PhoneNumber.GetUserPhoneNumber(c.Request().Context(), code)
	if err != nil {
		c.Logger().Fatal("微信小程序获取手机号错误: " + err.Error())
		return utils.JSONError(c, "微信小程序获取手机号错误")
	}

	if rs.ErrCode != 0 {
		c.Logger().Fatal("微信小程序获取手机号错误:" + strconv.Itoa(rs.ErrCode) + " " + rs.ErrMsg )
		return utils.JSONError(c, "微信小程序获取手机号错误")
	}

	phone := rs.PhoneInfo.PurePhoneNumber
	if phone == "" {
		return utils.JSONError(c, "微信手机号未填写")
	}


	var user models.User
	db := database.DB.Debug()
	db.Model(&models.User{}).First(&user, uid)

	c.Logger().Info("user.ID:" + strconv.Itoa(user.ID))
	if user.ID == 0 {
		return utils.JSONError(c, "系统错误：未登录")
	} else {
		db.Model(&user).Update("phone", phone)
		c.Logger().Info("phone: " + phone)
	}

	var resp loginResponse
	resp.UserInfo = user

	return utils.JSONSuccess(c, resp, "获取手机号成功")
}

// 小程序订阅消息的模板di
func MnpTmpl(c echo.Context) error {

	data := map[string]string{
		"course_audit": utils.CourseAuditApprovedTmplID,
		"enrollment_audit": utils.EnrollmentAuditApprovedTmplID,
		"course_start": utils.CourseStartTmplID,
	}

	return utils.JSONSuccess(c, data, "")
}


// 小程序用户确认接受订阅消息的回调
func MnpSubscribeMsgAccept(c echo.Context) error {
	uid := c.Get("uid").(int)

	var req map[string]interface{}

	if err := c.Bind(&req); err != nil {
		return utils.JSONError(c, "请求参数错误1")
	}

	var id int
	idFloat, ok := req["course_id"].(float64)
	if !ok {
		return utils.JSONError(c, "请求参数错误")
	} else {
		id = int(idFloat)
	}

	if id <= 0 {
		return utils.JSONError(c, "课程id不能为空")
	}

	// 从 map 中获取 tmpl_id
	rawTmplID, ok := req["tmpl_id"]
	if !ok {
		return utils.JSONError(c, "请求参数错误 tmpl_id missing")
	}

	// 类型断言为 []interface{}
	rawList, ok := rawTmplID.([]interface{})
	if !ok {
		return utils.JSONError(c, "请求参数错误 tmpl_id is not a list")
	}

	// 转换成 []string
	tmplIDs := make([]string, len(rawList))
	for i, v := range rawList {
		if str, ok := v.(string); ok {
			tmplIDs[i] = str
		} else {
			return utils.JSONError(c, "请求参数错误 tmpl_id element is not a string")
		}
	}

	if len(tmplIDs) < 1 {
		return utils.JSONError(c, "订阅消息id不能为空")
	}

	db := database.DB.Debug()

	for _, tmplID := range tmplIDs {
		if string(tmplID) == utils.CourseAuditApprovedTmplID {
			db.Model(&models.Course{}).Where("id = ?", id).Update("is_subscribed", 1)
		} else if string(tmplID) == utils.EnrollmentAuditApprovedTmplID {
			db.Model(&models.Enrollment{}).Where("course_id = ?", id).Where("user_id", uid).Update("is_audit_approved_subscribed", 1)
		} else if string(tmplID) == utils.CourseStartTmplID {
			db.Model(&models.Enrollment{}).Where("course_id = ?", id).Where("user_id", uid).Update("is_course_start_subscribed", 1)
		} 
	}

	return utils.JSONSuccess(c, nil, "订阅成功")
}
